home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / mac / files / t_sys5 / unixcpio.gz / unixnet.cpio / alloc.c < prev    next >
C/C++ Source or Header  |  1994-07-11  |  6KB  |  276 lines

  1. #include <stdio.h>
  2. #include "alloc.h"
  3. /* memory allocation routines
  4.  *
  5.  * Adapted from alloc routine in K&R; memory statistics and interrupt
  6.  * protection added for use with net package.
  7.  */
  8.  
  9. static HEADER base, *allocp = NULLHDR;
  10. static unsigned memfail;
  11.  
  12. /* Define ALLOCDEBUG for allocation recording. Note: works only with
  13.  * small memory model
  14.  */
  15. #ifdef    ALLOCDEBUG
  16. #define    NALLOC    150
  17. /* Map of allocated memory chunks */
  18. struct alloc {
  19.     char *addr;
  20.     unsigned size;
  21.     long pc;
  22. };
  23. struct alloc alloc[NALLOC];
  24. #endif
  25.  
  26. /* Allocate block of 'nb' bytes */
  27. char *
  28. malloc(nb)
  29. unsigned nb;
  30. {
  31.     HEADER *morecore();
  32.     register HEADER *p, *q;
  33.     register unsigned nu;
  34.     char i_state;
  35.  
  36. #ifdef    ALLOCDEBUG
  37.     struct alloc *ap;
  38.     unsigned short *ptr;
  39. #endif
  40.  
  41.     i_state = disable();
  42.     nu = ((nb + 3) >> 2) + 1;    /* Round up to full block, incl hdr */
  43.     if ((q = allocp) == NULLHDR){
  44.         base.s.ptr = allocp = q = &base;
  45.         base.s.size = 1;
  46.     }
  47.     for (p = q->s.ptr; ; q = p, p = p->s.ptr){
  48.         if (p->s.size >= nu){
  49.             /* This chunk is at least as large as we need */
  50.             if (p->s.size == nu){
  51.                 /* Perfect fit; remove from list */
  52.                 q->s.ptr = p->s.ptr;
  53.             } else {
  54.                 /* Carve out piece from end of entry */
  55.                 p->s.size -= nu;
  56.                 p += p->s.size;
  57.                 p->s.size = nu;
  58.             }
  59.             allocp = q;
  60.             p->s.ptr = p;    /* for auditing */
  61. #ifdef    ALLOCDEBUG
  62.             for(ap = alloc;ap < &alloc[NALLOC];ap++){
  63.                 if(ap->addr == NULLCHAR){
  64.                     ap->addr = (char *)(p+1);
  65.                     ap->size = nb;
  66.                     ptr = &nb;
  67. #ifdef    LARGECODE
  68.                     ap->pc = (long)ptr[-1] << 16 +
  69.                         (long)ptr[-2];
  70. #else
  71.                     ap->pc = (long)ptr[-1];
  72. #endif
  73.                     break;
  74.                 }
  75.             }
  76. #endif
  77.             restore(i_state);
  78.             return (char *)(p + 1);
  79.         }
  80.         if (p == allocp && (p = morecore(nu)) == NULLHDR){
  81.             memfail++;
  82.             restore(i_state);
  83.             return NULLCHAR;
  84.         }
  85.     }
  86. }
  87. /* Get more memory from the system and put it on the heap */
  88. HEADER *
  89. morecore(nu)
  90. unsigned nu;
  91. {
  92.     char *sbrk();
  93.     register char *cp;
  94.     register HEADER *up;
  95.  
  96.     if ((int)(cp = sbrk(nu << 2)) == -1)
  97.         return NULLHDR;
  98.     up = (HEADER *)cp;
  99.     up->s.size = nu;
  100.     up->s.ptr = up;    /* satisfy audit */
  101.     free((char *)(up + 1));
  102.     return allocp;
  103. }
  104. /* Grab as much memory as possible from the system and put it on the heap */
  105. unsigned
  106. grabcore()
  107. {
  108.     char *sbrk(),*cp;
  109.     register HEADER *up;
  110.     register unsigned int size;
  111.  
  112.     /* Initialize the heap pointers */
  113.     if (allocp == NULLHDR){
  114.         base.s.ptr = allocp = &base;
  115.         base.s.size = 1;
  116.     }
  117.     /* Find out where the break is */
  118.     cp = sbrk(0);
  119.     /* Now try to push it as high as possible */
  120.     for(size=256;;size += 256){
  121.         if(brk(cp + size) == -1)
  122.             break;
  123.     }
  124.  
  125.     up = (HEADER *)cp;
  126.     up->s.size = size / sizeof(HEADER);
  127.     up->s.ptr = up;    /* satisfy audit */
  128.     free((char *)(up + 1));
  129.     return size;
  130. }
  131.  
  132. /* Put memory block back on heap */
  133. free(blk)
  134. char *blk;
  135. {
  136.     register HEADER *p, *q;
  137.     unsigned short *ptr;
  138.     char i_state;
  139. #ifdef    ALLOCDEBUG
  140.     struct alloc *ap;
  141. #endif
  142.  
  143.     i_state = disable();
  144. #ifdef    ALLOCDEBUG
  145.     for(ap = alloc;ap < &alloc[NALLOC];ap++){
  146.         if(ap->addr == blk){
  147.             ap->addr = NULLCHAR;
  148.             break;
  149.         }
  150.     }
  151. #endif
  152.     p = (HEADER *)blk - 1;
  153.     /* Audit check */
  154.     if(p->s.ptr != p){
  155.         printf("p->s.ptr: 0x%x  p: 0x%x\n",p->s.ptr,p);fflush(stdout);
  156.         ptr = (unsigned short *)&blk;
  157.         printf("WARNING!! freeing garbage (0x%x) pc = 0x%x %x\n",blk,
  158.             ptr[-1],ptr[-2]);
  159.         fflush(stdout);
  160.         restore(i_state);
  161. #ifdef    Z80
  162.         printf("SP = 0x%x\n",getsp());
  163.         for(;;) ;
  164. #else
  165.         return;
  166. #endif
  167.     }
  168.     /* Search the free list looking for the right place to insert */
  169.     for(q = allocp; !(p > q && p < q->s.ptr); q = q->s.ptr){
  170.         /* Highest address on circular list? */
  171.         if(q >= q->s.ptr && (p > q || p < q->s.ptr))
  172.             break;
  173.     }
  174.     if(p + p->s.size == q->s.ptr){
  175.         /* Combine with front of this entry */
  176.         p->s.size += q->s.ptr->s.size;
  177.         p->s.ptr = q->s.ptr->s.ptr;
  178.     } else {
  179.         /* Link to front of this entry */
  180.         p->s.ptr = q->s.ptr;
  181.     }
  182.     if(q + q->s.size == p){
  183.         /* Combine with end of this entry */
  184.         q->s.size += p->s.size;
  185.         q->s.ptr = p->s.ptr;
  186.     } else {
  187.         /* Link to end of this entry */
  188.         q->s.ptr = p;
  189.     }
  190.     allocp = q;
  191.     restore(i_state);
  192. }
  193.  
  194. #ifdef    notdef
  195. /* Move existing block to new area */
  196. char *
  197. realloc(area,size)
  198. char *area;
  199. unsigned size;
  200. {
  201.     unsigned osize;
  202.     HEADER *hp;
  203.     char *cp;
  204.     char i_state;
  205.  
  206.     hp = ((HEADER *)area) - 1;
  207.     osize = (hp->s.size -1) << 2;
  208.  
  209.     /* Make sure nobody else comes in and takes it */
  210.     i_state = disable();
  211.     free(area);
  212.     if((cp = malloc(size)) != NULLCHAR && cp != area)
  213.         memcpy((char *)cp,(char *)area,size>osize? osize : size);
  214.     restore(i_state);
  215.     return cp;
  216. }
  217. #endif
  218. /* Allocate block of cleared memory */
  219. char *
  220. calloc(nelem,size)
  221. unsigned nelem;    /* Number of elements */
  222. unsigned size;    /* Size of each element */
  223. {
  224.     register unsigned i;
  225.     register char *cp;
  226. #ifdef    ALLOCDEBUG
  227.     struct alloc *ap;
  228.     short *ptr;
  229. #endif
  230.     i = nelem * size;
  231.     if((cp = malloc(i)) != NULLCHAR)
  232.         memset(cp,0,i);
  233. #ifdef    ALLOCDEBUG
  234.     if(cp == NULLCHAR)
  235.         return cp;
  236.     /* Adjust caller field to indicate real caller, not calloc() */
  237.     ptr = (short *)&nelem;
  238.     for(ap = alloc; ap < &alloc[NALLOC];ap++)
  239.         if(ap->addr == cp)
  240.             ap->pc = (long)ptr[-1];
  241. #endif
  242.     return cp;
  243. }
  244. /* Print free list map */
  245. memstat()
  246. {
  247.     HEADER *p;
  248.     unsigned total;
  249.  
  250.     printf("malloc fails %u\n",memfail);
  251.     total = 0;
  252.     p = &base;
  253.     do {
  254.         total += p->s.size * sizeof(HEADER);
  255.         printf("0x%x %u",(unsigned)p,p->s.size * sizeof(HEADER));
  256.         if(p == allocp)
  257.             printf(" <-- allocp\n");
  258.         else
  259.             printf("\n");
  260.         p = p->s.ptr;
  261.     } while(p != &base);
  262.     printf("Total: %u bytes\n",total);
  263. #ifdef    ALLOCDEBUG
  264.     {
  265.         struct alloc *ap;
  266.         printf("addr      size      caller\n");
  267.         for(ap = alloc;ap < &alloc[NALLOC];ap++){
  268.             if(ap->addr != NULLCHAR)
  269.                 printf("0x%-8x%-10d%-10lx\n",ap->addr,
  270.                     ap->size,ap->pc);
  271.         }
  272.     }
  273. #endif
  274.     fflush(stdout);
  275. }
  276.